package vn.cuhanh.utils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import vn.cuhanh.MainActivity;
import vn.cuhanh.R;
import vn.cuhanh.bean.Account;
import vn.cuhanh.dialog.AwardHistoryActivity;
import vn.cuhanh.sdk.BaseRequestListener;
import vn.cuhanh.sdk.ZingMeSDK;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;

import com.android.zing.ZME_Base;
import com.android.zing.ZME_DialogListener;
import com.android.zing.ZME_Error;
import com.android.zing.api.ZME_Me;
import com.android.zing.dialog.ZME_DialogError;

public class LoginHelper {
	private final String TAG = "CUHANH_LOGIN";
	private ZME_Base zme;
	private SharedPreferences mPrefs;
	private SharedPreferences.Editor editor;
	private static LoginHelper instance;
	private Context ctx;
	private Runnable callback;
	private boolean isAskForRetry = false;
	
	private LoginHelper() {
		super();
		this.zme = ZingMeSDK.getInstance().getZME_Base();
	}
	
	public static LoginHelper getInstance() {
		if(instance == null) {
			instance = new LoginHelper();
		}
		return instance;
	}
	
	public boolean isSessionExpired(Context ctx) {
		this.ctx = ctx;
		long now = Calendar.getInstance().getTimeInMillis();
		long expiredTime = zme.getAccessExpires();
		if(now < expiredTime) {
			return false;
		}
		return true;
	}

	public void requestZingMeLogin(final Context ctx, Runnable callback) {
		isAskForRetry = false;
		setCallback(callback);
    	String state = Double.toString(java.lang.Math.random());
    	final Activity activity = (Activity)ctx;
    	mPrefs = activity.getPreferences(Context.MODE_PRIVATE);
    	ZingMeSDK.getInstance().authorize(ctx, state, new ZME_DialogListener() {
    		public void onComplete(Bundle values ) {
    			if(zme.isSessionValid(ctx)) {
        			MainActivity.isLogin = true;
        			AwardHistoryActivity.listAwardHistory = null;
        			
        			editor = mPrefs.edit();
        			editor.putString("access_token", zme.getAccessToken());
        			editor.putLong("access_expires", zme.getAccessExpires());
        			editor.commit();
        			
        			getZingMeInfo(ctx);
    			}
    			else {
    				zme.logout(ctx);
    			}
    		
    		}
    		
    		public void onZmeError(ZME_Error e){
    			Log.d(TAG,"got error with ZME with error_code=" + e.getErrorCode());
    			if(e.getErrorCode() == ZME_Error.ZOAUTH_ERR_USER_HAD_LOGGED_OUT || e.getErrorCode() == ZME_Error.ZOAUTH_ERR_AUTHORIZED_CODE_EXPIRED || e.getErrorCode() == ZME_Error.ZOAUTH_ERR_WRONG_VALIDATE_APLLICATION) {
    				zme.logout(ctx);
    				//loginBtn.setVisibility(View.VISIBLE); ==> show login button or re-sho login form
    				activity.runOnUiThread(new Runnable() {
    	                public void run() {
    	                	requestZingMeLogin(ctx, getCallback()); //re-show login form
    	                }
    	            });  
    			}
    			if(e.getErrorCode() == 0 && !isAskForRetry) { //Show no network
    				((Activity)ctx).runOnUiThread(new Runnable() {
						
						@Override
						public void run() {
							// TODO Auto-generated method stub
							isAskForRetry = true;
							HelperFunc.showSimpleAlertDialog(ctx, null, ctx.getResources().getString(R.string.no_network_2), 
										ctx.getResources().getString(R.string.btn_retry_title), 
										new DialogInterface.OnClickListener() {
											
											@Override
											public void onClick(DialogInterface dialog, int which) {
												// TODO Auto-generated method stub
												requestZingMeLogin(ctx, getCallback());
											}
										}, 
										ctx.getResources().getString(R.string.bt_cancel_title), null, true);
						}
					});
    			}
    		};
    		
    	    public void onError(ZME_DialogError e){
    	    	Log.d(TAG, "got error with system");
    	    }

			public void onCancel() {
				// TODO Auto-generated method stub
				
			};
    	    
    	});
    }
	
	public void logout(Context ctx) {
		MainActivity.isLogin = false;
		MainActivity.username = null;
		MainActivity.userAccount = null;
		MainActivity.userId = 0;
		CuhanhDao.clearAll(ctx);
		zme.logout(ctx);
	}
	
	public void updateUserAccount(String jsonInfo) {
		try {
			JSONObject jsonObject = new JSONObject(jsonInfo);
			MainActivity.username = jsonObject.getString("userName");
			MainActivity.userId = jsonObject.getInt("passportId");
			Log.d("gameDetail", "json: " + jsonInfo + " username: " + MainActivity.username);
			
			MainActivity.userAccount = new Account(jsonObject.getInt("passportId"), jsonObject.getString("userName"), jsonObject.getInt("avatarNumber"),
					jsonObject.getString("charName"), jsonObject.getInt("score"), jsonObject.getInt("rank"), jsonObject.getInt("zingMeId"), jsonObject.getInt("zingMeGender"), 
					jsonObject.getString("zingMeAvatar"), jsonObject.getString("zingMeProfileUrl"), jsonObject.getString("zingMeName"), jsonObject.getString("phoneNo"));
			CuhanhDao.addAccountToDatabase(ctx, MainActivity.userAccount);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			HelperFunc.readStackTrace(e);
		} catch (Exception e) {
			HelperFunc.readStackTrace(e);
		}
	}
	
	public class MeInfoRequestListener extends BaseRequestListener {
		public void onComplete( Object data ) {
			final String info = data.toString();
			try {
				
				
				JSONObject jsonResponse = new JSONObject(info);
				String url = ctx.getResources().getString(R.string.getAndUpdateAccountInfoUrl);
				List<NameValuePair> ajaxParams = new ArrayList<NameValuePair>(6);
				ajaxParams.add(new BasicNameValuePair("username", jsonResponse.getString("username")));
				ajaxParams.add(new BasicNameValuePair("zingMeId", jsonResponse.getInt("id") + ""));
				ajaxParams.add(new BasicNameValuePair("gender", jsonResponse.getInt("gender") + ""));
				ajaxParams.add(new BasicNameValuePair("zingMeAvatar", jsonResponse.getString("tinyurl")));
				ajaxParams.add(new BasicNameValuePair("zingMeProfileUrl", jsonResponse.getString("profile_url")));
				ajaxParams.add(new BasicNameValuePair("zingMeName", jsonResponse.getString("displayname")));
				
				ajaxParams.add(new BasicNameValuePair("accessToken", zme.getAccessToken()));
				
				String response = HelperFunc.getDataFromSv(url, ajaxParams);
				if(response != null) {
					JSONObject fromDBResonse = new JSONObject(response);
					int result = fromDBResonse.getInt("result");
					if(result == 1) {
						updateUserAccount(fromDBResonse.getJSONObject("data").toString());
					}
				}
				if(getCallback() != null) {
					getCallback().run();
				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				HelperFunc.readStackTrace(e);
			}
		}
	}
	
	/**
	 * Call only when user is login
	 * @param ctx
	 * @param callBack
	 */
	public void getZingMeInfo(Context ctx) {
		this.ctx = ctx;
		ZME_Me mAsyncMe = ZingMeSDK.getInstance().getZME_Me();
		MeInfoRequestListener listener = new MeInfoRequestListener();
		mAsyncMe.getInfo("id,profile_url,username,displayname,gender,tinyurl,dob", listener);
	}

	public Runnable getCallback() {
		return callback;
	}

	public void setCallback(Runnable callback) {
		this.callback = callback;
	}
}
